package moc.gc;


import moc.tds.*;
import moc.type.DTYPE;
import moc.type.SIGNATURE;


/**
 * La machine TAM et ses fonctions de generation
 * @author marcel
 *
 */
public class MTAM extends AbstractMachine {
	
	
	
	private static int cpt = 0 ;

	private Register register = new Register("LB",0) ;
	@Override
	public String getSuffixe() {
		return "tam";
	}

	@Override
	public String getOperation(String operation) {
		String retour ;
		switch (operation) {
		case "moinsUnaire" : retour = "INeg" ;
							 break ;
		case "plusUnaire" : retour = "" ;
							break ;
		case "negation" : retour = "BNeg" ;
							break ;
		case "mult"     : retour ="IMul"  ;
						  break ;
		case "div"     : retour ="IDiv"  ;
		  break ;	
		case "mod"     : retour ="IMod"  ;
		  break ;
		case "et"     : retour ="BAnd"  ;
		  break ;
		case "plus"     : retour ="IAdd"  ;
		  break ;
		case "moins"     : retour ="ISub"  ;
		  break ;
		case "ou"     : retour ="BOr"  ;
		  break ;
		case "sup"     : retour ="IGtr"  ;
		  break ;
		  
		case "inf"     : retour ="ILss"  ;
		  break ;
		case "supeg"     : retour ="IGeq"  ;
		  break ;
		case "infeg"     : retour ="ISeq"  ;
		  break ;
		case "eg"     : retour ="IEq"  ;
		  break ;
		case "neg"     : retour ="INeq"  ;
		  break ;
		default : retour = null ;
		}
		return retour;
	}

	@Override
	public String genOperation(String operation) {
		
		return "SUBR "+operation +" ;  \n";
	}
	
	public String genChargementVariable(INFOVAR info){
		
		return "LOAD ("+info.getType().getTaille()+") "+info.getEmpl().getDep()+"["
				+info.getEmpl().getReg().getName()+"] ; \n" ;
	}
	
	
	public String genChargementAdresse(INFOVAR info){
		return "LOADA "+info.getEmpl().getDep()+"["
				+info.getEmpl().getReg().getName()+"] ; \n" ;
		
	}
	public String genEnregistrementVariable(INFOVAR info) {
		
		return "STORE  ("+info.getType().getTaille()+") "+info.getEmpl().getDep()+"["
				+info.getEmpl().getReg().getName()+"] ; \n" ;
		
	}
	
	public String genConstante(String constante){
		return "LOADL "+constante +";\n" ;
	}

	@Override
	public String genReturn(DTYPE type,int taille) {
		
		return "RETURN ( "+type.getTaille()+") "+taille+"; \n" ;
			
	}

	public String genPOP(DTYPE type,int taille){
		return "POP ("+type.getTaille()+") "+taille+" ; \n" ;
	}
	@Override
	public String genCast() {
		return "CAST";
	}

	@Override
	public String genChargmentMemoire(int taille) {
		// TODO Auto-generated method stub
		return "LOADI ("+taille+") ; \n";
	}
	public String genEnregistrementMemoire(int taille){
		return "STOREI ("+taille+") ; \n";
	}

	@Override
	public String genAppelFonction(String id,DTYPE retour,int taille) {
		
		return "CALL (LB) _"+id+"\n ;"	+";vider la liste des arguments ; \n";
				//+POP(retour,taille);
	}

	@Override
	public void debug(String pre, String chaine) {
		System.out.println(pre+" : "+chaine) ;
		
	}

	@Override
	public void debug(TDS tds) {
		for(String d : tds.keySet())
		System.out.println(d) ;
	}

	@Override
	public void debug(SIGNATURE sig) {
		for(String s : sig.keySet())
			System.out.println(s+"->"+sig.get(s).getType()+" @ "+sig.get(s).getDep()+"[LB]") ;
		
	}

	@Override
	public String genFonction(String id, String code) {
		
		return "_"+id+ " : ; \n"+code;
	}

	@Override
	public String genCond(String cond, String code1, String code2) {
		cpt++ ;
		return cond +"JUMPIF (0) sin_"+cpt+" ;\n"+code1+"JUMP suite_"+cpt+" ;\n"+"sin_"+cpt+
				": ;\n"+code2+"suite_"+cpt+": ;\n"
				;
	}

	@Override
	public void debug(TDS tds, int num) {
	if(tds != null){
		System.out.println("tds numero"+num);
	
		this.debug(tds);
		num++ ;
		
		this.debug(tds.getParente(), num);
		
	}	
	}

	@Override
	public String genWhile(String cond, String code) {
		cpt++ ;
		
		return "cond_"+cpt+": ;\n"+cond+"JUMPIF (0) suite_"+cpt+";\n"+code+"JUMP cond_"+cpt
				+";\n suite_"+cpt+": ; \n";
	}

	@Override
	public Register getRegister() {
		// TODO Auto-generated method stub
		return this.register;
	}

	@Override
	public String genAlloc(int taille) {
		// TODO Auto-generated method stub
		return "LOADL "+taille+";\n SUBR MAlloc ; \n";
	}


	
	


}
